/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"

#include <thread>
#include <fbxsdk.h>
#include "面/面.h"
#include "FBX模型加载保存.h"





#ifdef _DEBUG 

#pragma comment(lib, "D:/U/DEV/FBX_SDK/lib/vs2015/x64/debug/libfbxsdk-mt.lib")

#else

#pragma comment(lib, "D:/U/DEV/FBX_SDK/lib/vs2015/x64/release/libfbxsdk-mt.lib")

#endif

static fbxsdk::FbxManager* g_SdkManager = nullptr;
static fbxsdk::FbxScene* g_FbxScene = nullptr;
static fbxsdk::FbxGeometryConverter* g_Converter = nullptr;
static fbxsdk::FbxTime g_Time;

static std::vector<std::thread*> g线程池;



static void f_构建多边形物体网格(fbxsdk::FbxMesh* pMesh, S_物体* ob) {
	//fbxsdk::FbxNodeAttribute* const attr = g_Converter->Triangulate(pMesh, true);
	//pMesh = attr->GetNode()->GetMesh();
	S_多边形* 多边形 = f_surface_创建多边形();
	ob->m_UserData = 多边形;
	
	S_Mesh* 面轮廓网格 = f_ob_fromMesh(ob, 0);
	S_Mesh* 面网格 = f_ob_fromMesh(ob, 1);
	S_Mesh* 点网格 = f_ob_fromMesh(ob, 2);
	S_Mesh* 边网格 = f_ob_fromMesh(ob, 3);


	uint32 面数量 = pMesh->GetPolygonCount();
	uint32 顶点数量 = pMesh->GetControlPointsCount();
	uint32 法线数量 = pMesh->GetElementNormalCount();
	auto 顶点 = pMesh->GetControlPoints();
	auto p法线 = pMesh->GetElementNormal();
	auto p纹理坐标 = pMesh->GetElementUV();
	auto 映射模式 = p法线->GetMappingMode();

	//std::vector<S_VNT1> vertexs(顶点数量);
	S_Vec3Array* vertexs = (S_Vec3Array*)f_core_array_new(顶点数量, sizeof(vec3));
	S_Vec3Array* normals = (S_Vec3Array*)f_core_array_new(顶点数量, sizeof(vec3));
	//std::vector<vec3> normals(顶点数量);
	for (int32 i = 0; i < 顶点数量; ++i) {

		vertexs->ptr_userData[i] = {float32(顶点[i].mData[0]), float32(顶点[i].mData[1]), float32(顶点[i].mData[2])};
		//vertexs->ptr_userData[i] *= vec3{-1,1,1};
		if (映射模式 == FbxGeometryElement::eByPolygonVertex) {
			auto n = p法线->GetDirectArray().GetAt(i).mData;
			normals->ptr_userData[i] = vec3{float32(n[0]), float32(n[1]), float32(n[2])};// * vec3{-1,1,1};
		}

	}
	f_surface_添加多边形顶点(多边形, vertexs, normals);
	//f_surface_添加多边形法线(多边形, normals);
	f_core_array_free((S_Array*)vertexs);
	f_core_array_free((S_Array*)normals);






	多边形->m_UV层数量 = pMesh->GetUVLayerCount();
	int32 边数量 = pMesh->GetMeshEdgeCount();


	p纹理坐标->GetDirectArray();
	fbxsdk::FbxLayerElementArrayTemplate<FbxVector2>* pLockableArray;
	pMesh->GetTextureUV(&pLockableArray);


	std::vector<uint32> 每层UV坐标偏移(多边形->m_UV层数量);
	uint32 UV层索引偏移 = 0;

	FbxStringList pUVSetNameList;
	pMesh->GetUVSetNames(pUVSetNameList);

	pUVSetNameList.GetCount();


	//std::vector<fbxsdk::FbxLayerElementArrayTemplate<int>> 每层uv索引;
	std::vector<S_uVec2Array*> UV环_索引偏移;

	for (int32 i = 0; i < 多边形->m_UV层数量; ++i) {
		std::string uvName = pUVSetNameList.GetStringAt(i);

		auto au = pMesh->GetElementUV(uvName.c_str());
		auto auv = au->GetDirectArray();
		
		//每层uv索引.push_back(au->GetIndexArray());
		//auto ia = uvIndex.GetCount();
		//auto ib = uvIndex.GetAt(0);
		uint32 当前层UV数量 = auv.GetCount();
		
		每层UV坐标偏移[i] = UV层索引偏移;
		//uint32 当前层UV数量 = 0;
		for (int32 j = 0; j < 当前层UV数量; ++j) {
			auto uv坐标 = auv.GetAt(j);
			vec2 uv = {float32(uv坐标.Buffer()[0]), float32(uv坐标.Buffer()[1])};
			多边形->m_UV.push_back(uv);
		}
		UV层索引偏移 += 当前层UV数量;
		
		UV环_索引偏移.push_back((S_uVec2Array*)f_core_array_new(0, sizeof(uvec2)));
	}

	
	
	S_多边形元素* 元素 = (S_多边形元素*)f_core_array_new(面数量, sizeof(S_面*));


	std::vector<uint32> indexs;
	std::vector<std::vector<uint32>> uvIndex(多边形->m_UV层数量);
	std::vector<uvec2> uv环(多边形->m_UV层数量);
	//uv.reserve(面数量 * 4);

	uint32 index = 0;
	for (int32 i = 0; i < 面数量; ++i) {
		//uint32 面顶点数量 = pMesh->GetPolygonVertexCount();
		uint32 面顶点数量 = pMesh->GetPolygonSize(i);

		
		indexs.resize(面顶点数量);
		for (int32 j = 0; j < 面顶点数量; ++j) {
			uint32 顶点索引 = pMesh->GetPolygonVertex(i, j);
			uint32 顶点UV索引 = pMesh->GetTextureUVIndex(i, j);

			//pMesh->GetPolygonVertexUVs()
			indexs[j] = 顶点索引;

			for (int32 k = 0; k < 多边形->m_UV层数量; ++k) {
				auto fbxLayerUV = pMesh->GetLayer(k)->GetUVs();
				顶点UV索引 = fbxLayerUV->GetIndexArray().GetAt(index);
				if (k) {
					顶点UV索引 += 每层UV坐标偏移[k];
				}
				uvIndex[k].push_back(顶点UV索引);

				//uvIndex[k].push_back(顶点UV索引);
			}
			++index;
			//多边形->m_UV索引.push_back(顶点UV索引);
		}

		
		
		for (int32 k = 0; k < 多边形->m_UV层数量; ++k) {
			uv环[k].y = 面顶点数量;
			f_core_array_push_back((S_Array*)UV环_索引偏移[k], (uint8*)&uv环[k]);
		}

		S_面* 面 = f_surface_添加多边形面(多边形, indexs.data(), 面顶点数量);
		元素->ptr_userData[i] = 面;
		//面->uvLoopIndex[0] = UV环_索引偏移;
		//UV环_索引偏移.x += 面顶点数量;
		//f_surface_添加多边形纹理坐标(多边形, )
	}
	f_core_array_push_back((S_Array*)多边形->m_元素组, (uint8*)&元素);


	uint32 offset = 0;
	for (int32 k = 0; k < 多边形->m_UV层数量; ++k) {
		//if (k) {
		//	uvIndex[k-1].size();
		//}
		//offset = 面数量 * k;
		for (uint32 i = 0; i < UV环_索引偏移[k]->count; ++i) {
			UV环_索引偏移[k]->ptr_userData[i].x += offset;
			offset += UV环_索引偏移[k]->ptr_userData[i].y;
		}
	}
	
	offset = 0;
	for (int32 k = 0; k < 多边形->m_UV层数量; ++k) {
		offset = 每层UV坐标偏移[k];

		for (auto e : uvIndex[k]) {
			e += offset;
		}
		
		多边形->m_UV索引.insert(多边形->m_UV索引.end(), uvIndex[k].begin(), uvIndex[k].end());
	}

	for (int32 k = 0; k < 多边形->m_UV层数量; ++k) {
		f_surface_设置元素UV环(多边形, 元素, UV环_索引偏移[k], k);
	}

	f_surface_多边形转网格(多边形, 面网格, 点网格, 边网格, true);

	面轮廓网格->m_Bound = 面网格->m_Bound;
	面轮廓网格->m_包围盒 = 面网格->m_包围盒;



	//f_mesh_gen间接绘制网格属性(面网格, 1);
	//f_mesh_gen间接绘制网格属性(点网格, 1);
	//f_mesh_gen间接绘制网格属性(边网格, 1);
	//
	//auto 网格属性 = MeshProp_Init();
	//网格属性.m_Activate = 1;
	//f_mesh_set间接绘制网格属性(f_ob_fromMesh(ob), 网格属性);
}



static void f_构建变换动画曲线(fbxsdk::FbxAnimCurveNode* anode, S_动画曲线组* 曲线层, std::vector<float32>& 偏移补偿) {

	auto ChannelsCount = anode->GetChannelsCount();
	for (uint32 i = 0; i < ChannelsCount; ++i) {
		S_曲线通道* 通道 = f_an_添加曲线通道(曲线层, 3);

		uint32 曲线数量 = anode->GetCurveCount(i);
		if (曲线数量) {

			auto point = anode->GetCurve(i, 0);
			uint32 关键帧点数量 = point->KeyGetCount();

			float32 偏移 = 0;
			for (uint32 k = 0; k < 256; ++k) {
				auto key = point->KeyGet(k);
				auto tiem = key.GetTime();

				auto f = tiem.GetFrameRate(fbxsdk::FbxTime::EMode::eFrames30);
				float32 v = point->Evaluate(tiem);
				auto t = tiem.GetSecondDouble() * f;
				//f_an_添加曲线点(通道, t, v, {}, {});
			}


			/*for (uint32 k = 0; k < 关键帧点数量; ++k) {
				auto key = point->KeyGet(k);
				if (!k) {
					偏移 = key.GetValue();
				}

				

				auto tiem = key.GetTime();
				auto f = tiem.GetFrameRate(fbxsdk::FbxTime::EMode::eFrames30);
				auto t = tiem.GetSecondDouble() * f;
				//tiem.Get();
				//tiem.SetMilliSeconds(k);
				//auto t1 = key.GetTime();
				point->GetValue();
				vec2 左手柄 = { point->KeyGetLeftTangentVelocity(k) , point->KeyGetLeftTangentWeight(k) };
				vec2 右手柄 = { point->KeyGetRightTangentVelocity(k) , point->KeyGetRightTangentWeight(k) };

				float32 v = point->Evaluate(tiem);
				//float32 v = point->GetValue(k);
				//float32 v = key.GetValue();
				//if (k == 0) v = -v;
				//f_an_添加曲线点(通道, tiem.GetMilliSeconds(), point->GetValue()*100, 左手柄, 左手柄);
				//f_an_添加曲线点(通道, k, k, 左手柄, 左手柄); - 偏移
				f_an_添加曲线点(通道, t, v, 左手柄, 右手柄);
				//std::cout << "GetSecondDouble = " << t1.GetSecondDouble() << "   GetValue:" << point->GetValue(k) << std::endl;
			}*/

			偏移补偿.push_back(偏移);
		}

	}
}






static S_物体* f_构建网格(fbxsdk::FbxNode* pNode, S_设备环境& ctx) {
	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_多边形);
	S_多边形* 多边形 = f_surface_创建多边形();
	ob->m_UserData = 多边形;

	
	S_Mesh* 面网格 = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	S_Mesh* 点网格 = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	S_Mesh* 边网格 = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	
	f_ob_set数据槽数量(ob, 4);
	
	ob->f_setData(f_surface_创建实例(面网格), 0);
	ob->f_setData(面网格, 1);
	ob->f_setData(点网格, 2);
	ob->f_setData(边网格, 3);
	f_ob_fromMesh(ob, 0)->m_线宽 = 8;
	f_ob_fromMesh(ob, 0)->m_显示 = false;

	f_mesh_gen间接绘制网格属性(面网格, 1);
	f_mesh_gen间接绘制网格属性(点网格, 1);
	f_mesh_gen间接绘制网格属性(边网格, 1);


	auto 网格属性 = MeshProp_Init();
	网格属性.m_Activate = 0;
	for (uint32 i = 0; i < ob->m_DataNum; ++i) {
		f_mesh_set绘制属性(f_ob_fromMesh(ob, i), {});
		f_mesh_set间接绘制网格属性(f_ob_fromMesh(ob, i), 网格属性);
	}
	网格属性.m_Activate = 1;
	f_mesh_set间接绘制网格属性(f_ob_fromMesh(ob), 网格属性);

	


	fbxsdk::FbxMesh* pMesh = pNode->GetMesh();
	uint32 顶点数量 = pMesh->GetControlPointsCount();


	


	/*fbxsdk::FbxNodeAttribute* const attr = g_Converter->Triangulate(pMesh, true);
	pMesh = attr->GetNode()->GetMesh();
	
	
	uint32 面数量 = pMesh->GetPolygonCount();
	
	uint32 法线数量 = pMesh->GetElementNormalCount();
	auto 顶点 = pMesh->GetControlPoints();
	auto p法线 = pMesh->GetElementNormal();
	auto p纹理坐标 = pMesh->GetElementUV();
	auto 映射模式 = p法线->GetMappingMode();
	
	//std::vector<S_VNT1> vertexs(顶点数量);
	S_Vec3Array* vertexs = (S_Vec3Array*)f_core_array_new(顶点数量, sizeof(vec3));
	S_Vec3Array* normals = (S_Vec3Array*)f_core_array_new(顶点数量, sizeof(vec3));
	//std::vector<vec3> normals(顶点数量);
	for (int32 i = 0; i < 顶点数量; ++i) {
		vertexs->ptr_userData[i] = {float32(顶点[i].mData[0]), float32(顶点[i].mData[1]), float32(顶点[i].mData[2])};
		if (映射模式 == FbxGeometryElement::eByPolygonVertex) {
			auto n = p法线->GetDirectArray().GetAt(i).mData;
			normals->ptr_userData[i] = {float32(n[0]), float32(n[1]), float32(n[2])};
		}
	}
	f_surface_添加多边形顶点(多边形, vertexs);
	f_surface_添加多边形法线(多边形, normals);
	


	int32 UV层数量 = pMesh->GetUVLayerCount();
	int32 边数量 = pMesh->GetMeshEdgeCount();


	FbxStringList pUVSetNameList;
	pMesh->GetUVSetNames(pUVSetNameList);
	
	std::vector<vec2> uv;
	uv.reserve(面数量 * 4);
	for (int32 i = 0; i < 面数量; ++i) {
		//uint32 面顶点数量 = pMesh->GetPolygonVertexCount();
		uint32 面顶点数量 = pMesh->GetPolygonSize(i);

		std::vector<uint32> indexs;
		indexs.reserve(128);
		for (int32 j = 0; j < 面顶点数量; ++j) {
			FbxVector2 pUV;
			bool pUnmapped;
			pMesh->GetPolygonVertexUV(i, 0, pUVSetNameList.GetStringAt(j), pUV, pUnmapped);

			uv.push_back({float32(pUV.mData[0]), float32(pUV.mData[2])});
			indexs.push_back(pMesh->GetPolygonVertex(i, j));
		}

		f_surface_添加多边形面(多边形, indexs.data(), 面顶点数量);
	}


	f_surface_多边形转网格(多边形, 面网格, 边网格, true);*/
	
	std::thread* t1 = new std::thread(f_构建多边形物体网格, pMesh, ob);
	g线程池.push_back(t1);


	auto 骨骼组数量 = pMesh->GetDeformerCount(FbxDeformer::eSkin);
	uint32 骨骼数量 = 0;
	std::vector<float32> 权重;
	std::vector<uint32> 骨骼ID(顶点数量, 0xffffffff);
	uint32* bonesID = 骨骼ID.data();

	//uint32 tmp = 0;
	for (uint32 i = 0; i < 骨骼组数量; ++i) {
		auto ClusterCount = ((FbxSkin*)pMesh->GetDeformer(i, FbxDeformer::eSkin))->GetClusterCount();

		权重.resize(权重.size() + ClusterCount * 顶点数量);
		//权重.resize(顶点数量);
		float32* weigth = 权重.data();
		
		for (uint32 j = 0; j < ClusterCount; ++j) {
			auto skin = ((FbxSkin*)pMesh->GetDeformer(i, FbxDeformer::eSkin));
			auto skinA = ((fbxsdk::FbxSkeleton*)pMesh->GetDeformer(i, FbxDeformer::eSkin));
			//if (!skin) continue;
			
			fbxsdk::FbxCluster* lCluster = skin->GetCluster(j);
			//std::cout << "FbxSkeleton[k] B = " << lCluster->GetName() << " : " << lCluster->GetUniqueID() << std::endl;

			int k, lIndexCount = lCluster->GetControlPointIndicesCount();
			int* lIndices = lCluster->GetControlPointIndices();
			double* lWeights = lCluster->GetControlPointWeights();
			

			for (k = 0; k < lIndexCount; k++) {
				uint32 Indices = lIndices[k];
				uint32 offset = j * 顶点数量 + Indices;
				//std::cout << "offset A = " << offset << " : " << lWeights << std::endl;
				weigth[offset] = lWeights[k];
				
				uint8* bones_prt = (uint8*)&(bonesID[Indices]);
				//std::cout << "bones_prt = " << bones_prt << " : " << bonesID << std::endl;
				for (uint8 b = 0; b < 4; ++b) {
					if(bones_prt[b] >= 255){
						bones_prt[b] = uint8(j);
					}
				}
			}
		}

		骨骼数量 += ClusterCount;
	}


	S_骨骼属性 骨骼属性;

	if (权重.size() && 骨骼ID.size()) {
		f_surface_fill顶点权重(面网格, 权重, 骨骼ID, 骨骼属性);
	}
	return ob;
}

static S_物体* f_构建骨骼(fbxsdk::FbxNode* pNode, S_设备环境& ctx) {
	fbxsdk::FbxSkeleton* Skeleton = pNode->GetSkeleton();
	
	float32 骨骼长度 = Skeleton->GetLimbLengthDefaultValue();
	float32 骨骼大小 = Skeleton->GetLimbNodeSizeDefaultValue();
	骨骼长度 = Skeleton->LimbLength;
	
	
	//std::cout << "FbxSkeleton[k] = " << Skeleton->GetUniqueID() << " : " << Skeleton->GetName() << std::endl;
	//Skeleton->GetDefaultImplementation
	S_物体* 骨骼 = f_ob_创建骨骼(nullptr);


	auto 移动 = pNode->LclTranslation.EvaluateValue();
	auto 旋转 = pNode->LclRotation.EvaluateValue();
	auto 缩放 = pNode->LclScaling.EvaluateValue();
	//auto 移动 = pNode->GetGeometricTranslation(fbxsdk::FbxNode::eDestinationPivot);
	//auto 旋转 = pNode->GetGeometricRotation(fbxsdk::FbxNode::eDestinationPivot);
	//auto 缩放 = pNode->GetGeometricScaling(fbxsdk::FbxNode::eDestinationPivot);
	骨骼->f_set位置(移动[0], 移动[1], 移动[2]);
	骨骼->f_set旋转(旋转[0], 旋转[1], 旋转[2]);
	骨骼->f_set缩放(缩放[0], 缩放[1], 缩放[2]);


	std::vector<float32> 偏移补偿;
	auto anode = pNode->LclTranslation.GetCurveNode();
	if (anode) {
		骨骼->m_位置 = f_an_创建曲线通道(3);
		//f_构建变换动画曲线(anode, 骨骼->m_位置, 偏移补偿);

		骨骼->m_变换.location.x = 偏移补偿[0];
		骨骼->m_变换.location.y = 偏移补偿[1];
		骨骼->m_变换.location.z = 偏移补偿[2];
	}
	else 骨骼->m_位置 = nullptr;

	//anode = r.GetCurveNode();
	//anode = pNode->QuaternionInterpolate.GetCurveNode();
	偏移补偿.clear();
	anode = pNode->RotationOffset.GetCurveNode();
	if(!anode) anode = pNode->LclRotation.GetCurveNode();
	if (anode) {
		骨骼->m_旋转 = f_an_创建曲线通道(3);
		//f_构建变换动画曲线(anode, 骨骼->m_旋转, 偏移补偿);

		骨骼->m_变换.rotation.x = 偏移补偿[0];
		骨骼->m_变换.rotation.y = 偏移补偿[1];
		骨骼->m_变换.rotation.z = 偏移补偿[2];
	}
	else 骨骼->m_旋转 = nullptr;

	偏移补偿.clear();
	anode = pNode->LclScaling.GetCurveNode();
	if (anode) {
		骨骼->m_缩放 = f_an_创建曲线通道(3);
		//f_构建变换动画曲线(anode, 骨骼->m_缩放, 偏移补偿);

		骨骼->m_变换.scale.x = 偏移补偿[0];
		骨骼->m_变换.scale.y = 偏移补偿[1];
		骨骼->m_变换.scale.z = 偏移补偿[2];
	}
	else 骨骼->m_缩放 = nullptr;


	
	auto type = Skeleton->GetSkeletonType();
	switch (type) {
	case fbxsdk::FbxSkeleton::EType::eRoot: {
		break;
	}
	case fbxsdk::FbxSkeleton::EType::eLimb: {
		break;
	}
	case fbxsdk::FbxSkeleton::EType::eLimbNode: {
		break;
	}
	case fbxsdk::FbxSkeleton::EType::eEffector: {
		break;
	}
	default:
		break;
	}


	for (int32 i = 0; i < pNode->GetChildCount(); ++i) {
		
		//auto 移动 = pNode->GetGeometricTranslation(fbxsdk::FbxNode::eDestinationPivot);
	//	auto 旋转 = pNode->GetGeometricRotation(fbxsdk::FbxNode::eDestinationPivot);
		//auto 缩放 = pNode->GetGeometricScaling(fbxsdk::FbxNode::eDestinationPivot);
		S_物体* 子骨骼 = f_构建骨骼(pNode->GetChild(i), ctx);
		子骨骼->m_是否实例 = true;

		f_ob_add子物体(骨骼, 子骨骼);
	}

	return 骨骼;
}

static void f_提取骨骼动画曲线(S_Tree* 骨骼) {
	auto b = DEF_骨骼(骨骼);

	//for (auto* c = 骨骼->prt_tree; c; c = c->ptr_尾) {
	//	if(c->ptr_userData) f_提取骨骼动画曲线((S_Tree*)c->ptr_userData);
	//}
}

static void f_查找FBX节点(std::vector<S_物体*>& objs, S_物体* 父物体, fbxsdk::FbxNode* pNode, S_设备环境& ctx) {
	S_物体* ob = 父物体;


	uint32 动画栈数量 = pNode->GetSrcObjectCount();
	for (uint32 i = 0; i < 动画栈数量; ++i) {
		std::string name;
		if (动画栈数量) {

			auto FbxAnimStack = fbxsdk::FbxCast<fbxsdk::FbxAnimStack>(pNode->GetSrcObject(i));
			if (FbxAnimStack) {
				name = FbxAnimStack->GetName();
			}

		}
	}

	if (pNode->GetNodeAttribute()) {
		if (objs.size()) ob = objs.back();
		
	
		

		switch (pNode->GetNodeAttribute()->GetAttributeType()) {
		case fbxsdk::FbxNodeAttribute::eMesh: {
			//auto 移动 = pNode->GetGeometricTranslation(fbxsdk::FbxNode::eDestinationPivot);
			//auto 旋转 = pNode->GetGeometricRotation(fbxsdk::FbxNode::eDestinationPivot);
			//auto 缩放 = pNode->GetGeometricScaling(fbxsdk::FbxNode::eDestinationPivot);
			//auto 移动 = pNode->LclTranslation;
			//auto 旋转 = pNode->LclRotation;
			//auto 缩放 = pNode->LclScaling;
			//auto 移动 = pNode->LclTranslation.EvaluateValue();
			//auto 旋转 = pNode->LclRotation.EvaluateValue();
			//auto 缩放 = pNode->LclScaling.EvaluateValue();
			
			//auto 旋转 = pNode->GetPostRotation(fbxsdk::FbxNode::eDestinationPivot);
			//auto 旋转1 = pNode->GetPreRotation(fbxsdk::FbxNode::eDestinationPivot);
			//auto 缩放1 = pNode->GetScalingOffset(fbxsdk::FbxNode::eDestinationPivot);
			//auto 缩放2 = pNode->GetScalingPivot(fbxsdk::FbxNode::eDestinationPivot);
			
			auto 移动 = pNode->EvaluateGlobalTransform().GetT();
			auto 旋转 = pNode->EvaluateGlobalTransform().GetR();
			auto 缩放 = pNode->EvaluateGlobalTransform().GetS();
			//auto 移动 = pNode->LclTranslation.Get().mData;
			//auto 旋转 = pNode->LclRotation.Get().mData;
			//auto 缩放 = pNode->LclScaling.Get().mData;
			

			auto t1 = pNode->EvaluateGlobalTransform().mData[0];
			auto t2 = pNode->EvaluateGlobalTransform().mData[1];
			auto t3 = pNode->EvaluateGlobalTransform().mData[2];
			auto t4 = pNode->EvaluateGlobalTransform().mData[3];

			/*auto l1 = pNode->EvaluateLocalTransform().mData[0];
			auto l2 = pNode->EvaluateLocalTransform().mData[1];
			auto l3 = pNode->EvaluateLocalTransform().mData[2];
			auto l4 = pNode->EvaluateLocalTransform().mData[3];*/
			//pNode->GetPostRotation
			//auto anode = pNode->LclTranslation.GetCurveNode();
			//auto 位置 = f_an_创建曲线层();
			//f_构建变换动画曲线(anode, 位置);
			//auto t = pNode->GetTransform();
			std::string name = pNode->GetName();
			
			S_物体* ob = f_构建网格(pNode, ctx);
			ob->f_set位置(移动[0], 移动[1], 移动[2]);
			ob->f_set旋转(旋转[0], 旋转[1], 旋转[2]);
			ob->f_set缩放(缩放[0], 缩放[1], 缩放[2]);

			ob->m_Name = f_StringToWString(name);
			objs.push_back(ob);
			break;
		}
		case fbxsdk::FbxNodeAttribute::eSkeleton: {
			return;
			ob = f_构建骨骼(pNode, ctx);

			f_ob_add子物体(父物体, ob);
			f_ob_创建矩阵(ob, ctx);
			//f_提取骨骼动画曲线(ob->m_骨骼);
			//f_ob_构建骨骼(ctx, ob, 父物体);
			//uint32 开始ID = 0;
			//f_ob_构建骨骼虚拟体实例ID(ob, 开始ID);
			return;
		}
		}
	}
	

	for (int32 i = 0; i < pNode->GetChildCount(); ++i) {
		f_查找FBX节点(objs, ob, pNode->GetChild(i), ctx);
	}
}



static void f_初始化FBX环境() {
	g_SdkManager = fbxsdk::FbxManager::Create();
	FbxIOSettings* 导入导出设置 = FbxIOSettings::Create(g_SdkManager, IOSROOT);
	导入导出设置->SetBoolProp(EXP_ASCIIFBX, true);
	导入导出设置->SetBoolProp(IMP_FBX_MATERIAL, true);
	g_SdkManager->SetIOSettings(导入导出设置);

	std::string lExtension = "dll";
	FbxString lPath = FbxGetApplicationDirectory();
	g_SdkManager->LoadPluginsDirectory(lPath.Buffer(), lExtension.c_str());


	g_FbxScene = fbxsdk::FbxScene::Create(g_SdkManager, "MBT");
	if (!g_FbxScene) {
		FBXSDK_printf("Error: Unable to create FBX scene!\n");
		exit(1);
	}


	g_Converter = new fbxsdk::FbxGeometryConverter(g_SdkManager);
}


void f_Ex加载FBX模型(std::vector<S_物体*>& objs, const std::string& path, S_设备环境& ctx) {
	if (g_SdkManager == nullptr) {
		f_初始化FBX环境();
	}
	
	
	int32 lFileMajor, lFileMinor, lFileRevision;
	int32 lSDKMajor, lSDKMinor, lSDKRevision;

	fbxsdk::FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision);

	char* 转换路径 = nullptr;
	FbxAnsiToUTF8(path.c_str(), 转换路径);
	FbxImporter* lImporter = FbxImporter::Create(g_SdkManager, "");
	const bool lImportStatus = lImporter->Initialize(转换路径, -1, g_SdkManager->GetIOSettings());
	//const bool lImportStatus = lImporter->Initialize(path.c_str(), -1, g_SdkManager->GetIOSettings());
	//const bool lImportStatus = lImporter->Initialize(path.c_str(), -1, g_SdkManager->GetIOSettings());

	FbxIOSettings* ioSettings = FbxIOSettings::Create(g_SdkManager, IOSROOT);


	delete[] 转换路径;
	//const bool lImportStatus = lImporter->Initialize("I:/TEMP/猴头.fbx", -1, g_SdkManager->GetIOSettings());
	lImporter->GetFileVersion(lFileMajor, lFileMinor, lFileRevision);


	if (!lImportStatus) {
		FbxString error = lImporter->GetStatus().GetErrorString();
		std::cout << "error:" << error << " " << lImporter->GetStatus().GetCode() << std::endl;

		if (lImporter->GetStatus().GetCode() == fbxsdk::FbxStatus::eInvalidFileVersion) {
			FBXSDK_printf("FBX file format version for this FBX SDK is %d.%d.%d\n", lSDKMajor, lSDKMinor, lSDKRevision);
			FBXSDK_printf("FBX file format version for file '%s' is %d.%d.%d\n\n", path, lFileMajor, lFileMinor, lFileRevision);
		}
	}

	if (lImporter->IsFBX()) {
		//return;
	}

	g_FbxScene->Clear();
	
	

	
	// Import the scene.
	bool lStatus = lImporter->Import(g_FbxScene);
	if (lStatus == false && lImporter->GetStatus().GetCode() == fbxsdk::FbxStatus::ePasswordError) {
		return;
	}

	

	fbxsdk::FbxAxisSystem axis(
		fbxsdk::FbxAxisSystem::EUpVector::eYAxis,
		fbxsdk::FbxAxisSystem::eParityEven,
		fbxsdk::FbxAxisSystem::eRightHanded
	);

	//fbxsdk::FbxAxisSystem axis(fbxsdk::FbxAxisSystem::EPreDefinedAxisSystem::eOpenGL);
	//fbxsdk::FbxAxisSystem axis(fbxsdk::FbxAxisSystem::EPreDefinedAxisSystem::eMayaYUp);
	axis.ConvertScene(g_FbxScene);


	lImporter->Destroy();
	
	//g_Scene->SetUserDataPtr();
	fbxsdk::FbxNode* lRootNode = g_FbxScene->GetRootNode();
	f_查找FBX节点(objs, nullptr, lRootNode, ctx);
	

	for (auto& e : g线程池) {
		(*e).join();
		delete e;
	}
	g线程池.clear();
	return;

	uint32 动画栈数量 = g_FbxScene->GetSrcObjectCount();
	for (uint32 i = 0; i < 动画栈数量; ++i) {
		
		fbxsdk::FbxAnimStack* pAnimStack = fbxsdk::FbxCast<fbxsdk::FbxAnimStack>(g_FbxScene->GetSrcObject(i));
		if (pAnimStack) {
			int32 numAnimLayers = pAnimStack->GetMemberCount();

			std::string name = pAnimStack->GetInitialName();
			std::string name1 = pAnimStack->GetName();
			auto obj = pAnimStack->GetReferenceTo();
			auto ReferencedByCount = pAnimStack->GetReferencedByCount();

			for (uint32 l = 0; l < numAnimLayers; ++l) {
				fbxsdk::FbxAnimLayer* lAnimLayer = fbxsdk::FbxCast<fbxsdk::FbxAnimLayer>(pAnimStack->GetMember(l));

				name = lAnimLayer->GetName();
				ReferencedByCount = lAnimLayer->GetReferencedByCount();
				int32 SrcObjectCount = lAnimLayer->GetSrcObjectCount();
				int32 SrcPropertyCount = lAnimLayer->GetSrcPropertyCount();
				int32 MemberCount = lAnimLayer->GetMemberCount();


				lRootNode->LclTranslation.GetCurveNode();
				auto node = lRootNode->LclRotation.GetCurveNode();
				//node->GetCurve();
				fbxsdk::FbxAnimCurve* lAnimCurve = lRootNode->LclTranslation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
				if (!lAnimCurve) continue;
				fbxsdk::FbxNodeAttribute* lNodeAttribute = lRootNode->GetNodeAttribute();
				//fbxsdk::FbxAnimCurve* lAnimCurve = lNodeAttribute->Color.GetCurve<fbxsdk::FbxAnimCurve>(lAnimLayer, FBXSDK_CURVENODE_COLOR_RED);
				//fbxsdk::FbxAnimCurveNode* lCurveNode = lRootNode->GetCurveNode(pAnimLayer);
				lAnimCurve->KeyGetCount();

			}
		}
		
	}
	

	g_FbxScene->Clear();
}

















//三角化操作
/*for (int i = 0; i < m_Scene->GetGeometryCount(); ++i) {
	FbxGeometry* geometry = m_Scene->GetGeometry(i);

	if (!geometry->Is<fbxsdk::FbxMesh>() || !((fbxsdk::FbxMesh*)geometry)->IsTriangleMesh()) {
		triangulate.push_back(geometry);
	}
}

for (std::vector<FbxGeometry*>::iterator it = triangulate.begin(); it != triangulate.end(); ++it) {
	FbxNodeAttribute* const attr = converter.Triangulate(*it, true);
}*/




